#pragma once
/*
    项目抽象层的实现，以便于后面派生类对其进行复用和扩展
*/
#include "fields.hpp"
#include <string>
#include <memory>
#include <functional>
using std::string;

namespace tmh_rpc
{
    // 消息类的抽象
    class BaseMessage
    {
    public:
        using ptr = std::shared_ptr<BaseMessage>;

        virtual ~BaseMessage() {}
        virtual void setId(const string &id)
        {
            _rid = id;
        }
        virtual string rid() { return _rid; }

        virtual void setMType(const MType &mtype)
        {
            _mtype = mtype;
        }
        virtual MType mtype() { return _mtype; }

        // 对于结构化的消息类型和id进行序列化操作
        virtual string serialize() = 0;

        // 对于返回的字符串进行反序列化操作 得到_mtype和_rid
        virtual bool deserialize(const string &msg) = 0;

        // 对于反序列化之后的字段进行校验
        virtual bool check() = 0;

    private:
        MType _mtype;
        string _rid;
    };

    // 缓冲区的抽象
    class BaseBuffer
    {
    public:
        using ptr = std::shared_ptr<BaseBuffer>;

        virtual size_t readableSize() = 0; // 返回当前缓冲区数据大小

        virtual int32_t peekInt32() = 0;  // 尝试从缓冲区中取出4字节数据
        virtual void retrieveInt32() = 0; // 删除缓冲区4字节数据
        virtual int32_t readInt32() = 0;  // 读取缓冲区4字节数据，并且删除数据

        virtual string retrieveAsString(size_t len) = 0; // 从缓冲区取出指定长度的数据
    };

    // 应用层协议的抽象
    class BaseProtocol
    {
    public:
        using ptr = std::shared_ptr<BaseProtocol>;

        // 1. 判断当前缓冲区的数据是否足够处理
        virtual bool canProcessed(const BaseBuffer::ptr &buff) = 0;
        // 2. 对缓冲区数据进行处理，将其写入msg中
        virtual bool onMessage(const BaseBuffer::ptr &buff, BaseMessage::ptr &msg) = 0;
        // 3. 将消息msg进行序列化, 返回字符串 -- 发送
        virtual string serialize(const BaseMessage::ptr &msg) = 0;
    };

    // 连接层的抽象
    class BaseConnection
    {
    public:
        using ptr = std::shared_ptr<BaseConnection>;
        // 发送消息 [需要Protocol类中的序列化函数] (_protocol.serialize())
        virtual void send(const BaseMessage::ptr &msg) = 0;

        // 关闭连接
        virtual void shutdown() = 0;
        // 连接状态
        virtual bool connected() = 0;
    };

    // 服务端的抽象
    // 连接建立成功的回调函数
    using ConnectionCallback = std::function<void(const BaseConnection::ptr &)>;

    // 关闭连接的回调函数
    using CloseCallback = std::function<void(const BaseConnection::ptr &)>;

    // 信息处理的回调函数
    using MessageCallback = std::function<void(const BaseConnection::ptr &, BaseMessage::ptr &)>;
    class BaseServer
    {
    public:
        using ptr = std::shared_ptr<BaseServer>;

        // 对回调函数进行设置
        virtual void setConnectionCallback(const ConnectionCallback &cb)
        {
            _cb_connection = cb;
        }
        virtual void setCloseCallback(const CloseCallback &cb)
        {
            _cb_close = cb;
        }
        virtual void setMessageCallback(const MessageCallback &cb)
        {
            _cb_message = cb;
        }

        // 服务端启动
        virtual void start() = 0;

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };

    // 客户端的抽象
    class BaseClient
    {
    public:
        using ptr = std::shared_ptr<BaseClient>;

        // 对回调函数进行设置
        virtual void setConnectionCallback(const ConnectionCallback &cb)
        {
            _cb_connection = cb;
        }
        virtual void setCloseCallback(const CloseCallback &cb)
        {
            _cb_close = cb;
        }
        virtual void setMessageCallback(const MessageCallback &cb)
        {
            _cb_message = cb;
        }

        // 客户端对服务端发起连接
        virtual void connect() = 0;

        // 关闭连接
        virtual void shutdown() = 0;

        // 发送消息
        virtual bool send(const BaseMessage::ptr &msg) = 0;

        // 获取连接对象
        virtual BaseConnection::ptr connection() = 0;

        // 判断连接是否正常
        virtual bool connected() = 0;

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };
}
